package com.antunnel.basicorm.core;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.antunnel.common.util.ReflectionUtils;
import com.antunnel.common.util.StrUtils;


public class OrmConverter
{
  public static Class getPropertyType(String str)
  {
    return ((PropertyType)Enum.valueOf(PropertyType.class, str)).getValue();
  }

  public static Object getPropertyValue(Object value, Class propertyType, String matchType)
  {
    if ((null != matchType) && ("like".equals(matchType))) {
      value = "%" + value + "%";
    }
    return ReflectionUtils.convertStringToObject(value, propertyType);
  }

  public static void assemblyQuery(StringBuffer queryString, Map<String, String> filterMap, List valueList)
  {
    String[] temp = null;
    Iterator it = filterMap.entrySet().iterator();
    Map.Entry entry = null;
    while (it.hasNext()) {
      entry = (Map.Entry)it.next();
      Object key = entry.getKey();
      getQueryReal(null, queryString, filterMap, key.toString(), null, valueList);
    }

    boolean isOrder = false;

    for (String o : filterMap.keySet()) {
      if (o.toString().startsWith("order")) {
        temp = o.split("_");
        if (queryString.toString().indexOf("order by") < 0)
          queryString.append(" order by");
        else {
          queryString.append(",");
        }
        queryString.append(" " + temp[1] + " " + (String)filterMap.get(o));
        if (!isOrder) {
          isOrder = true;
        }
      }
    }
    if (!isOrder)
      queryString.append(" order by id");
  }

  public static void getOrder(StringBuffer queryString, Map<String, String> filterMap)
  {
    String[] temp = null;
    for (String o : filterMap.keySet())
      if (o.toString().startsWith("order")) {
        temp = o.split("_");
        if (queryString.toString().indexOf("order by") < 0)
          queryString.append(" order by");
        else {
          queryString.append(",");
        }
        queryString.append(" " + temp[1] + " " + (String)filterMap.get(o));
      }
  }

  public static String getMatchType(MatchType matchType)
  {
    if (MatchType.EQ.equals(matchType))
      return "=";
    if (MatchType.NEQ.equals(matchType))
      return "<>";
    if (MatchType.LIKE.equals(matchType))
      return "like";
    if (MatchType.LE.equals(matchType))
      return "<=";
    if (MatchType.LT.equals(matchType))
      return "<";
    if (MatchType.GE.equals(matchType))
      return ">=";
    if (MatchType.GT.equals(matchType))
      return ">";
    if (MatchType.IS.equals(matchType))
      return "is";
    if (MatchType.ISNOT.equals(matchType)) {
      return "is not";
    }
    throw new IllegalArgumentException("无法得到属性比较类型.");
  }

  public static void getQueryReal(String tableName, StringBuffer queryString, Map<String, String> filterMap, String queryName, String propertyName, List valueList)
  {
    if ((StrUtils.isNullOrBlank(filterMap.get(queryName))) && (queryName.indexOf("IS") < 0))
    {
      return;
    }
    String[] temp = queryName.replace("__", ".").split("_");
    if (temp.length < 5) {
      return;
    }
    if (null != propertyName) {
      temp[2] = propertyName;
    }
    if (null != tableName) {
      temp[2] = (tableName + "." + temp[2]);
    }
    MatchType matchType = null;
    Class propertyType = null;
    Object propertyValue = null;
    try {
      matchType = (MatchType)Enum.valueOf(MatchType.class, temp[3]);
    } catch (RuntimeException e) {
      throw new IllegalArgumentException("filter名称" + queryName + "没有按规则编写,无法得到属性比较类型.", e);
    }
    try
    {
      propertyType = ((PropertyType)Enum.valueOf(PropertyType.class, temp[4])).getValue();
    } catch (RuntimeException e) {
      throw new IllegalArgumentException("filter名称" + queryName + "没有按规则编写,无法得到属性值类型.", e);
    }

    propertyValue = getPropertyValue(filterMap.get(queryName), propertyType, getMatchType(matchType));

    if ((!MatchType.IS.equals(matchType)) && (!MatchType.ISNOT.equals(matchType)))
    {
      queryString.append(" " + temp[1] + " " + temp[2] + " " + getMatchType(matchType) + " ?");

      valueList.add(propertyValue);
    } else {
      queryString.append(" " + temp[1] + " " + temp[2] + " " + getMatchType(matchType) + " null");
    }
  }

  public static void getQuery(StringBuffer queryString, Map<String, String> filterMap, String queryName, List valueList)
  {
    getQuery(null, queryString, filterMap, queryName, valueList);
  }

  public static void getQuery(String tableName, StringBuffer queryString, Map<String, String> filterMap, String queryName, List valueList)
  {
    String[] temp = queryName.replace("__", ".").split("_");
    if (temp.length < 5) {
      return;
    }
    String propertyName = temp[2];
    getQueryReal(tableName, queryString, filterMap, queryName, propertyName, valueList);
  }

  public static enum PropertyType
  {
    S(String.class), I(Integer.class), L(Long.class), D(Double.class), T(Date.class), 
    B(Boolean.class);

    private Class<?> clazz;

    private PropertyType(Class<?> clazz) {
      this.clazz = clazz;
    }

    public Class<?> getValue() {
      return this.clazz;
    }
  }

  public static enum MatchType
  {
    EQ, NEQ, LIKE, LT, GT, LE, GE, IS, ISNOT;
  }
}